package com.imooc.user.thrift;

import com.imooc.thrift.message.MessageService;
import com.imooc.thrift.user.UserService;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import org.springframework.stereotype.Component;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Auther: zhaozeyang
 * @Date: 2018/8/19 19:31
 * @Description:
 */
@Component
public class ServiceProvider {


    public final static Map<String, TTransport> map1 = new ConcurrentHashMap<>();

    private String serviceIp = "127.0.0.1";

    private int serverPort = 7911;

    private int messageServerPort = 9090;

    public UserService.Client getUserService() throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        return getUserService(serviceIp, serverPort);
    }

    public MessageService.Client getMessageService() throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        return getMessageService(serviceIp, messageServerPort);
    }

    public UserService.Client getUserService(String serviceIp, int serverPort) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        return getService(serviceIp, serverPort, UserService.Client.class);
    }

    public MessageService.Client getMessageService(String serviceIp, int serverPort) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        return getService(serviceIp, serverPort, MessageService.Client.class);
    }

    public <T> T getService(String ip, int port, Class<T> clientType) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        TTransport tTransport = map1.get("transport");
        if (tTransport == null) {
            TSocket socket = new TSocket(ip, port, 3000);
            tTransport = new TFramedTransport(socket);
            try {
                tTransport.open();
                map1.put("transport", tTransport);
            } catch (TTransportException e) {
                e.printStackTrace();
                return null;
            }
        }
        TProtocol protocol = new TBinaryProtocol(tTransport);
        Class<TProtocol>[] paramClassTypes = new Class[]{TProtocol.class};
        Constructor<T> constructor = clientType.getConstructor(paramClassTypes);
        T client = constructor.newInstance(protocol);
        return client;
    }
}
